package cn.wit.summit.chwan.dot;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.Nullable;

import com.google.gson.Gson;


import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import cn.wit.summit.chwan.Stat.StatFactory;
import cn.wit.summit.chwan.models.db.DotRequestTable;
import cn.wit.summit.chwan.models.event.DotEvent;
import cn.wit.summit.chwan.models.request.StartClientRequest;
import cn.wit.summit.chwan.models.request.StartGameRequest;
import cn.wit.summit.chwan.models.response.DotResultModel;
import cn.wit.summit.chwan.net.BuildRequestUtils;
import cn.wit.summit.chwan.net.NetCallBack;
import cn.wit.summit.chwan.net.okhttplib.OkHttpUtil;
import cn.wit.summit.chwan.utils.AppInfoUtil;
import cn.wit.summit.chwan.utils.HttpUtils;
import cn.wit.summit.chwan.utils.LogUtils;
import cn.wit.summit.chwan.utils.MD5Util;
import cn.wit.summit.chwan.utils.NetWorkUtils;
import cn.wit.summit.chwan.utils.StringUtils;
import cn.wit.summit.chwan.utils.SystemInfoUtils;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import pub.devrel.easypermissions.EasyPermissions;

/**
 * Created by Alan on 2017/12/27.
 */

public class DotService extends Service {
    protected static final String TAG = "DotService>>>:";

    private LocalBinder binder = new LocalBinder();
    private String token = "";
    private int reGetNum = 0;

    private Gson mGson = new Gson();
    private boolean isEvent = false;

    /**
     * 创建Binder对象，返回给客户端即Activity使用，提供数据交换的接口
     */
    public class LocalBinder extends Binder {
        // 声明一个方法，getService。（提供给客户端调用）
        public DotService getService() {
            // 返回当前对象LocalService,这样我们就可在客户端端调用Service的公共方法了
            return DotService.this;
        }
    }

    /**
     * 绑定服务时才会调用
     * 必须要实现的方法
     * @param intent
     * @return
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        LogUtils.e(TAG + "onBind");
        return binder;
    }

    /**
     * 解除绑定时调用
     * @return
     */
    @Override
    public boolean onUnbind(Intent intent) {
        LogUtils.e(TAG + "onUnbind");
        return super.onUnbind(intent);
    }

    /**
     * 首次创建服务时，系统将调用此方法来执行一次性设置程序（在调用 onStartCommand() 或 onBind() 之前）。
     * 如果服务已在运行，则不会调用此方法。该方法只被调用一次
     */
    @Override
    public void onCreate() {
        LogUtils.e(TAG + "onCreate");
        super.onCreate();
        EventBus.getDefault().register(this);
    }

    /**
     * 每次通过startService()方法启动Service时都会被回调。
     * @param intent
     * @param flags
     * @param startId
     * @return
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtils.e(TAG + "onStartCommand");
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                startDotWork();
            }
        }, 3000);
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 服务销毁时的回调
     */
    @Override
    public void onDestroy() {
        LogUtils.e(TAG + "onDestroy");
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onUserEvent(DotEvent eventData) {
        isEvent = true;
        startDotWork();
    }

    public void startDotWork() {

        LogUtils.e(TAG + "startDotWork");
        if (NetWorkUtils.isNetworkConnected(this)) {
//            if ("".equals(token)) {
//                reGetNum = 0;
//                getWebToken();
//            } else {
                seedDotInfo();
//            }
        }
    }

    private void seedDotInfo() {
        LogUtils.e(TAG + "seedDotInfo");
        LogUtils.e("stat seedDotInfo");
        List<DotRequestTable> list = DotRequestManager.getInstance().getAllDot();
        DotRequestManager.getInstance().deleteDownloadAll();
        if (list!=null && list.size()>0) {
            for (int i=0;i<list.size();i++) {

                LogUtils.e("stat seedDotInfo i="+i);
                final DotRequestTable temp = list.get(i);
                HttpUtils.doPost(DotConfig.DotSeedUrl, DotConfig.appId, SystemInfoUtils.getInstance(this).getDeviceId()
                        , SystemInfoUtils.getInstance(this).getIMEI()
                        , token, temp.getJsonData(), new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                Message msg = new Message();
                                msg.what = DotConfig.seedDotFail;
                                handler.sendMessage(msg);
                                temp.setId(0L);
                                DotRequestManager.getInstance().insertDownload(temp);
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                String str = response.body().string();
                                LogUtils.e(TAG + " stat seedDotInfo onResponse");
                                if (StringUtils.isEmpty(str)) return;
                                try {
                                    DotResultModel dotResultModel2 = new Gson().fromJson(str, DotResultModel.class);
                                    dotResultModel2.setId(temp.getId());
                                    if (dotResultModel2.getCode()!=200){
                                        temp.setId(0L);
                                        DotRequestManager.getInstance().insertDownload(temp);
                                    }
                                    LogUtils.e(TAG + "response:"+str);
                                    Message msg = new Message();
                                    msg.what = DotConfig.seedDotSuccess;
                                    msg.obj = dotResultModel2;
                                    handler.sendMessage(msg);
                                } catch (Exception e) {
                                    LogUtils.e(TAG + " Gson Fail");
                                }
                            }
                        });
            }

//            String jsonStr = mGson.toJson(parms);

//            LogUtils.e(TAG+"jsonStr:"+jsonStr);

        } else {
            LogUtils.e(TAG + "upload all");
            if (!isEvent)
                setTimer();
            else
                isEvent = false;
        }
    }

    private void getWebToken() {
        LogUtils.e(TAG + "getWebToken>>reGetNum:"+reGetNum);
        if (reGetNum>=10) return;
        String imei = AppInfoUtil.getIMEI(this);
        String auth = MD5Util.stringToMD5(DotConfig.appId+"_"+imei+"_"+DotConfig.privateKey);
        HttpUtils.doGet(DotConfig.DotGetTokenUrl+"?auth="+auth, DotConfig.appId, imei, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Message msg = new Message();
                msg.what = DotConfig.getTokenFail;
                handler.sendMessage(msg);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                LogUtils.e(TAG + "response:"+str);
                Message msg = new Message();
                msg.what = DotConfig.getTokenSuccess;
                msg.obj = str;
                handler.sendMessage(msg);
            }
        });
    }

    private void setTimer() {
        LogUtils.e(TAG + "setTimer");
        AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
        int five = 1000 * 60 * 10; // 这是间隔时间
        long triggerAtTime = SystemClock.elapsedRealtime() + five;
        Intent i = new Intent(this, AlarmReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        } else {
            manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        }
    }

    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case DotConfig.getTokenFail://
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            reGetNum += 1;
                            getWebToken();
                        }
                    }, 3000);
                    break;
                case DotConfig.getTokenSuccess://
                    reGetNum = 0;
                    String str = (String) msg.obj;
//                    DotResultModel dotResultModel = new Gson().fromJson(str, DotResultModel.class);
//                    if (dotResultModel.getErrorCode()==0) {
//                        token = dotResultModel.getData().getToken();
//                        startDotWork();
//                    } else {
//                        new Handler().postDelayed(new Runnable() {
//                            @Override
//                            public void run() {
//                                reGetNum += 1;
//                                getWebToken();
//                            }
//                        }, 3000);
//                    }
                    break;
                case DotConfig.seedDotFail:
                    checkUpFailNum();
                    break;
                case DotConfig.seedDotSuccess:
                    DotResultModel dotResultModel2 = (DotResultModel) msg.obj;
                    LogUtils.e("stat seedDotSuccess "+dotResultModel2.getId());
                    if (dotResultModel2.getCode()==200) {
                    LogUtils.e("stat seedDotSuccess "+dotResultModel2.getId());
//                        DotRequestManager.getInstance().deleteById(dotResultModel2.getId());
                        DotRequestManager.getInstance().deleteDownload(dotResultModel2.getId());
//                        LogUtils.e("stat seedDotSuccess  start"+dotResultModel2.getId());
//                        startDotWork();
                    } else {
                        checkUpFailNum();
                        startDotWork();
                    }
                    break;
            }
        }
    };

    private void checkUpFailNum() {
        List<DotRequestTable> temp = DotRequestManager.getInstance().getAllDot();
        if (temp!=null || temp.size()>0) {
            for (int i=0;i<temp.size();i++) {
                DotRequestTable te = temp.get(i);
                int num = te.getUploadNum();
                if (num>5) {
                    DotRequestManager.getInstance().deleteDownload(te.getId());
                } else {
                    te.setUploadNum(te.getUploadNum()+1);
                }
            }
        }
    }
}
